<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>物理中磁感线流向效果演示</title>
  <style>
    body {
      font-family: 'Microsoft YaHei', sans-serif;
      background-color: #f5f7fa;
      margin: 0;
      padding: 20px;
      display: flex;
      flex-direction: column;
      align-items: center;
      min-height: 100vh;
    }
    
    .container {
      max-width: 800px;
      background-color: white;
      border-radius: 12px;
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
      padding: 30px;
      margin: 20px 0;
    }
    
    h1 {
      color: #333;
      text-align: center;
      margin-bottom: 30px;
      font-size: 28px;
    }
    
    .description {
      color: #555;
      line-height: 1.6;
      margin-bottom: 30px;
      font-size: 16px;
    }
    
    .magnet-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      margin: 20px 0 40px;
    }
    
    .controls {
      display: flex;
      gap: 15px;
      margin-top: 20px;
    }
    
    button {
      background-color: #4a89dc;
      color: white;
      border: none;
      padding: 10px 20px;
      border-radius: 6px;
      cursor: pointer;
      font-size: 16px;
      transition: background-color 0.3s;
    }
    
    button:hover {
      background-color: #3a70c0;
    }
    
    .legend {
      display: flex;
      justify-content: center;
      gap: 20px;
      margin-top: 20px;
    }
    
    .legend-item {
      display: flex;
      align-items: center;
      gap: 8px;
    }
    
    .legend-color {
      width: 20px;
      height: 20px;
      border-radius: 50%;
    }
    
    .footer {
      margin-top: 30px;
      text-align: center;
      color: #888;
      font-size: 14px;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>✨ 物理中磁感线流向动态演示 🧲</h1>
    
    <div class="description">
      <p>磁感线是描述磁场空间分布的一种方式，它从N极出发，经过外部空间，再回到S极。下面的动态演示展示了磁感线的流向和特性。</p>
      <p>通过观察蓝色粒子的运动，可以直观理解磁感线的流向。</p>
    </div>
    
    <div class="magnet-container">
      <svg width="600" height="400" id="magneticFieldSVG">
        <!-- 背景 -->
        <rect x="0" y="0" width="600" height="400" fill="#f8f9fa" rx="10" ry="10" />
        
        <!-- 磁铁 -->
        <rect x="200" y="150" width="200" height="100" rx="5" ry="5" fill="#e0e0e0" stroke="#333" stroke-width="2" />
        <rect x="200" y="150" width="100" height="100" rx="0" ry="0" fill="#ff9999" stroke="#333" stroke-width="2" />
        <rect x="300" y="150" width="100" height="100" rx="0" ry="0" fill="#9999ff" stroke="#333" stroke-width="2" />
        
        <!-- 磁极标识 -->
        <text x="250" y="200" font-size="32" font-weight="bold" fill="#cc0000" text-anchor="middle">N</text>
        <text x="350" y="200" font-size="32" font-weight="bold" fill="#0000cc" text-anchor="middle">S</text>
        
        <!-- 标题 -->
        <text x="300" y="80" font-size="24" font-weight="bold" fill="#333" text-anchor="middle">磁感线流向演示</text>
        
        <!-- 磁感线将通过JavaScript动态生成 -->
      </svg>
      
      <div class="controls">
        <button id="speedUp">加速</button>
        <button id="speedDown">减速</button>
        <button id="toggleAnimation">暂停/播放</button>
        <button id="addLines">增加磁感线</button>
      </div>
      
      <div class="legend">
        <div class="legend-item">
          <div class="legend-color" style="background-color: #ff9999;"></div>
          <span>N极</span>
        </div>
        <div class="legend-item">
          <div class="legend-color" style="background-color: #9999ff;"></div>
          <span>S极</span>
        </div>
        <div class="legend-item">
          <div class="legend-color" style="background-color: #0066cc;"></div>
          <span>磁感线流向</span>
        </div>
      </div>
    </div>
    
    <div class="footer">
      <p>© 2025 物理教学演示 | 磁感线流向效果GIF</p>
    </div>
  </div>
  
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      const svg = document.getElementById('magneticFieldSVG');
      let animationSpeed = 3; // 默认动画速度（秒）
      let isAnimationPaused = false;
      let lineCount = 0;
      
      // 创建磁感线
      function createMagneticLine(startX, startY, controlPoints, lineType = 'outside') {
        const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        
        let d = `M ${startX} ${startY}`;
        controlPoints.forEach(point => {
          d += ` Q ${point.cp1x} ${point.cp1y} ${point.x} ${point.y}`;
        });
        
        path.setAttribute('d', d);
        path.setAttribute('fill', 'none');
        path.setAttribute('stroke', lineType === 'outside' ? '#3366cc' : '#6633cc');
        path.setAttribute('stroke-width', '2');
        path.setAttribute('stroke-opacity', '0.7');
        
        // 创建箭头标记
        const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
        const markerId = `arrow-${startX}-${startY}-${Date.now()}`;
        marker.setAttribute('id', markerId);
        marker.setAttribute('viewBox', '0 0 10 10');
        marker.setAttribute('refX', '5');
        marker.setAttribute('refY', '5');
        marker.setAttribute('markerWidth', '4');
        marker.setAttribute('markerHeight', '4');
        marker.setAttribute('orient', 'auto');
        
        const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        arrow.setAttribute('d', 'M 0 0 L 10 5 L 0 10 z');
        arrow.setAttribute('fill', lineType === 'outside' ? '#3366cc' : '#6633cc');
        
        marker.appendChild(arrow);
        svg.appendChild(marker);
        
        path.setAttribute('marker-mid', `url(#${markerId})`);
        path.setAttribute('marker-end', `url(#${markerId})`);
        
        svg.appendChild(path);
        
        // 创建动画效果
        for (let i = 0; i < 3; i++) {
          const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
          circle.setAttribute('r', '3');
          circle.setAttribute('fill', lineType === 'outside' ? '#0066cc' : '#6600cc');
          
          const animateMotion = document.createElementNS('http://www.w3.org/2000/svg', 'animateMotion');
          animateMotion.setAttribute('dur', `${animationSpeed}s`);
          animateMotion.setAttribute('begin', `${i * animationSpeed / 3}s`);
          animateMotion.setAttribute('repeatCount', 'indefinite');
          animateMotion.setAttribute('path', d);
          
          circle.appendChild(animateMotion);
          svg.appendChild(circle);
          
          // 存储动画元素以便后续控制
          animations.push(animateMotion);
        }
        
        return path;
      }
      
      // 存储所有动画元素
      const animations = [];
      
      // 创建外部磁感线
      const outsideLines = [
        // 左侧磁感线（从N极出发）
        {
          start: { x: 200, y: 170 },
          controls: [
            { cp1x: 150, cp1y: 130, x: 100, y: 200 },
            { cp1x: 150, cp1y: 270, x: 200, y: 230 }
          ]
        },
        {
          start: { x: 200, y: 190 },
          controls: [
            { cp1x: 120, cp1y: 150, x: 80, y: 200 },
            { cp1x: 120, cp1y: 250, x: 200, y: 210 }
          ]
        },
        // 右侧磁感线（进入S极）
        {
          start: { x: 400, y: 170 },
          controls: [
            { cp1x: 450, cp1y: 130, x: 500, y: 200 },
            { cp1x: 450, cp1y: 270, x: 400, y: 230 }
          ]
        },
        {
          start: { x: 400, y: 190 },
          controls: [
            { cp1x: 480, cp1y: 150, x: 520, y: 200 },
            { cp1x: 480, cp1y: 250, x: 400, y: 210 }
          ]
        },
        // 顶部磁感线
        {
          start: { x: 220, y: 150 },
          controls: [
            { cp1x: 250, cp1y: 80, x: 300, y: 80 },
            { cp1x: 350, cp1y: 80, x: 380, y: 150 }
          ]
        },
        // 底部磁感线
        {
          start: { x: 220, y: 250 },
          controls: [
            { cp1x: 250, cp1y: 320, x: 300, y: 320 },
            { cp1x: 350, cp1y: 320, x: 380, y: 250 }
          ]
        }
      ];
      
      // 创建内部磁感线（从S极到N极）
      const insideLines = [
        {
          start: { x: 300, y: 180 },
          controls: [
            { cp1x: 280, cp1y: 200, x: 250, y: 200 }
          ]
        },
        {
          start: { x: 300, y: 220 },
          controls: [
            { cp1x: 280, cp1y: 200, x: 250, y: 200 }
          ]
        }
      ];
      
      // 添加外部磁感线
      outsideLines.forEach(line => {
        createMagneticLine(line.start.x, line.start.y, line.controls, 'outside');
        lineCount++;
      });
      
      // 添加内部磁感线
      insideLines.forEach(line => {
        createMagneticLine(line.start.x, line.start.y, line.controls, 'inside');
        lineCount++;
      });
      
      // 控制按钮功能
      document.getElementById('speedUp').addEventListener('click', function() {
        if (animationSpeed > 0.5) {
          animationSpeed -= 0.5;
          updateAnimationSpeed();
        }
      });
      
      document.getElementById('speedDown').addEventListener('click', function() {
        animationSpeed += 0.5;
        updateAnimationSpeed();
      });
      
      document.getElementById('toggleAnimation').addEventListener('click', function() {
        isAnimationPaused = !isAnimationPaused;
        animations.forEach(anim => {
          if (isAnimationPaused) {
            anim.setAttribute('dur', '999999s'); // 极慢速度相当于暂停
          } else {
            anim.setAttribute('dur', `${animationSpeed}s`);
          }
        });
      });
      
      document.getElementById('addLines').addEventListener('click', function() {
        if (lineCount < 20) { // 限制最大磁感线数量
          // 添加新的外部磁感线
          const randomOffset = Math.floor(Math.random() * 30);
          const newOutsideLine = {
            start: { x: 200, y: 180 + randomOffset },
            controls: [
              { cp1x: 150 - randomOffset, cp1y: 150, x: 100 - randomOffset, y: 200 },
              { cp1x: 150 - randomOffset, cp1y: 250, x: 200, y: 220 - randomOffset }
            ]
          };
          
          createMagneticLine(newOutsideLine.start.x, newOutsideLine.start.y, newOutsideLine.controls, 'outside');
          lineCount++;
          
          // 添加对应的右侧磁感线
          const newRightLine = {
            start: { x: 400, y: 180 + randomOffset },
            controls: [
              { cp1x: 450 + randomOffset, cp1y: 150, x: 500 + randomOffset, y: 200 },
              { cp1x: 450 + randomOffset, cp1y: 250, x: 400, y: 220 - randomOffset }
            ]
          };
          
          createMagneticLine(newRightLine.start.x, newRightLine.start.y, newRightLine.controls, 'outside');
          lineCount++;
        }
      });
      
      // 更新所有动画的速度
      function updateAnimationSpeed() {
        animations.forEach(anim => {
          anim.setAttribute('dur', `${animationSpeed}s`);
        });
      }
      
      // 添加交互效果 - 鼠标悬停时显示磁感线方向说明
      svg.addEventListener('mousemove', function(event) {
        const rect = svg.getBoundingClientRect();
        const x = event.clientX - rect.left;
        const y = event.clientY - rect.top;
        
        // 检查是否在磁铁区域内
        if (x >= 200 && x <= 400 && y >= 150 && y <= 250) {
          // 在磁铁内部，可以显示提示
          showTooltip(x, y);
        } else {
          hideTooltip();
        }
      });
      
      // 创建提示元素
      let tooltip = document.createElementNS('http://www.w3.org/2000/svg', 'g');
      tooltip.setAttribute('id', 'tooltip');
      tooltip.style.display = 'none';
      svg.appendChild(tooltip);
      
      function showTooltip(x, y) {
        // 清除旧的提示内容
        while (tooltip.firstChild) {
          tooltip.removeChild(tooltip.firstChild);
        }
        
        // 创建提示背景
        const bg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        bg.setAttribute('x', x + 10);
        bg.setAttribute('y', y - 30);
        bg.setAttribute('width', '140');
        bg.setAttribute('height', '25');
        bg.setAttribute('fill', 'rgba(0,0,0,0.7)');
        bg.setAttribute('rx', '5');
        tooltip.appendChild(bg);
        
        // 创建提示文本
        const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        text.setAttribute('x', x + 15);
        text.setAttribute('y', y - 12);
        text.setAttribute('fill', 'white');
        text.setAttribute('font-size', '12');
        
        // 根据位置确定提示内容
        if (x < 300) {
          text.textContent = "N极：磁感线出发点";
        } else {
          text.textContent = "S极：磁感线终点";
        }
        
        tooltip.appendChild(text);
        tooltip.style.display = 'block';
      }
      
      function hideTooltip() {
        tooltip.style.display = 'none';
      }
    });
  </script>
</body>
</html>